﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace modelisation_protocole
{
    public partial class formModelisation : Form
    {
        const int MAX_TRANSMISSION_CNX = 3;
        const int MAX_TRANSMISSION_TRANSFERT = 2;
        static int nbPaquets = 1;
        static int nbPaquetsTransfere = 0;

        public formModelisation()
        {
            InitializeComponent();
        }

        private void radioFEN_CheckedChanged(object sender, EventArgs e)
        {
            if (radioFEN.Checked) {
                txtbxSetFenLen.Enabled = true;
            } else {
                txtbxSetFenLen.Enabled = false;
                txtbxSetFenLen.Text = "1";
            }

        }

        private void radioSW_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void traitementsRetourRepos()
        {
            txtbxFenLen.Text = txtbxSetFenLen.Text;
            nbPaquetsTransfere = 0;
            txtbxNbTr.Text = "0";
            txtbxFenLen.Text = "";
        }

        private void btnContinue_Click(object sender, EventArgs e)
        {
            Etape uneEtape = new Etape();
            if (tabctrlEtapes.SelectedTab == tabRepos) {
                //Initialisation de toutes les variables
                uneEtape = new Etape(null, "CNX", "L-CONNECT.demande", null, tabctrlEtapes.SelectedTab, tabAttAckConnexion);
                txtbxFenLen.Text = txtbxSetFenLen.Text;
                txtbxNbTr.Text = "1";
                nbPaquets = Convert.ToInt32(txtbxFenLen.Text);
                lstLog.Items.Clear();
            } else if (tabctrlEtapes.SelectedTab == tabAttAckConnexion) {
                //Si la connexion est acquitté par le récepteur
                if (radioAckCnx.Checked) {
                    if (nbPaquets == 1)
                    {
                        uneEtape = new Etape("CNX-ACK", "DATA", "L-CONNECT.confirmation(OK)", "L-CONNECT.indication", tabctrlEtapes.SelectedTab, tabAttAckTransfert);
                    }
                    else
                    {
                        uneEtape = new Etape("CNX-ACK", "DATA-1", "L-CONNECT.confirmation(OK)", "L-CONNECT.indication", tabctrlEtapes.SelectedTab, tabAttAckTransfert);
                    }
                    txtbxNbTr.Text = "1";
                    ++nbPaquetsTransfere;
                } else {
                    string strPaquet = null;
                    //Si non-acquittement
                    if (radioNackCnx.Checked)
                    {
                        strPaquet = "CNX-NACK";
                    }
                    int nbTrans = Convert.ToInt32(txtbxNbTr.Text);
                    if (nbTrans < MAX_TRANSMISSION_CNX) {
                        txtbxNbTr.Text = (nbTrans + 1).ToString();
                        uneEtape = new Etape(strPaquet, "CNX", "L-CONNECT.confirmation(NOK)", "L-CONNECT.indication");
                    } else {
                        uneEtape = new Etape(null, null, "L-ABANDON.indication", null, tabctrlEtapes.SelectedTab, tabRepos);
                        traitementsRetourRepos();
                        nbPaquetsTransfere = 0;
                        txtbxFenLen.Text = txtbxSetFenLen.Text;
                    }
                }
            } else if (tabctrlEtapes.SelectedTab == tabAttAckTransfert) {
                //Si transfert acquitté
                if (radioAckTran.Checked)
                {
                    uneEtape.MsgEmetteur = "L-DATA.confirmation";
                    uneEtape.MsgRecepteur = "L-DATA.indication";
                    if (nbPaquets == 1)
                    {
                        uneEtape.PaquetVersEmetteur = "ACK";
                    }
                    else
                    {
                        uneEtape.PaquetVersEmetteur = "ACK-" + nbPaquetsTransfere.ToString();
                    }
                    if (nbPaquets > 1 && nbPaquets - nbPaquetsTransfere != 0)
                    {
                        ++nbPaquetsTransfere;
                        uneEtape.PaquetVersRecepteur = "DATA-" + nbPaquetsTransfere.ToString();
                    }
                    else
                    {
                        uneEtape.PaquetVersRecepteur = "DISC";
                        uneEtape.NextTabPage = tabDeconnexion;
                        uneEtape.CurrentTabPage = tabctrlEtapes.SelectedTab;
                        txtbxNbTr.Text = "1";
                    }
                }
                else
                {
                    //Si non-acquittement
                    if (radioNackTran.Checked)
                    {
                        if (nbPaquets == 1)
                        {
                            uneEtape.PaquetVersEmetteur = "NACK";
                        }
                        else
                        {
                            uneEtape.PaquetVersEmetteur = "NACK-" + nbPaquetsTransfere.ToString();
                        }
                        if (nbPaquets == 1)
                        {
                            uneEtape.PaquetVersRecepteur = "DATA";
                        }
                        else
                        {
                            uneEtape.PaquetVersRecepteur = "DATA-" + nbPaquetsTransfere.ToString();
                        }
                        int nbTrans = Convert.ToInt32(txtbxNbTr.Text);
                        if (nbTrans < MAX_TRANSMISSION_CNX)
                        {
                            txtbxNbTr.Text = (nbTrans + 1).ToString();
                        }
                        else
                        {
                            uneEtape = new Etape("COUP", null, "L-COUPURE.indication", null, tabctrlEtapes.SelectedTab, tabRepos);
                            traitementsRetourRepos();
                            nbPaquetsTransfere = 0;
                            txtbxFenLen.Text = txtbxSetFenLen.Text;
                        }
                    }
                    else if (radioTimeOutTran.Checked)
                    {
                        uneEtape = new Etape("COUP", null, "L-COUPURE.indication", null, tabctrlEtapes.SelectedTab, tabRepos);
                        traitementsRetourRepos();
                    }
                }
            } else if (tabctrlEtapes.SelectedTab == tabDeconnexion) {
                if (radioAckDeco.Checked)
                {
                    uneEtape = new Etape(null, null, null, null, tabctrlEtapes.SelectedTab, tabRepos);
                    traitementsRetourRepos();
                    uneEtape.PaquetVersEmetteur = "ACK";
                    uneEtape.MsgEmetteur = "L-DISCONNECT.indication";
                    uneEtape.MsgRecepteur = "L-DISCONNECT.indication";
                }
                else if (radioNackDeco.Checked)
                {
                    int nbTrans = Convert.ToInt32(txtbxNbTr.Text);
                    txtbxNbTr.Text = (nbTrans + 1).ToString();
                    if (nbTrans <= 1)
                    {
                        uneEtape = new Etape("NACK", "DISC", null, "L-DISCONNECT.indication");
                    }
                    else
                    {
                        uneEtape = new Etape("NACK", null, null, "L-DISCONNECT.indication", tabctrlEtapes.SelectedTab, tabRepos);
                        traitementsRetourRepos();
                    }
                }
            }
            traitementAffichages(uneEtape);
        }

        //Dans les logs, les traitements suivent l'ordre : Primitive récepteur, Paquet récepteur, Primitive émetteur, Paquet émetteur
        private void traitementAffichages(Etape uneEtape)
        {
            lblEmetVersRecept.Text = "";
            picEmetVersRecept.Visible = false;
            lblReceptVersEmet.Text = "";
            picReceptVersEmet.Visible = false;
            lblMsgRecepteur.Text = "";
            lblMsgEmetteur.Text = "";

            if (uneEtape.MsgRecepteur != null) //Primitive récepteur
            {
                lblMsgRecepteur.Text = uneEtape.MsgRecepteur;
                lstLog.Items.Add("Primitive '" + uneEtape.MsgRecepteur + "' reçue par le répecteur");
            }
            if (uneEtape.PaquetVersEmetteur != null) //Paquet émetteur vers récepteur
            {
                lblReceptVersEmet.Text = uneEtape.PaquetVersEmetteur;
                lstLog.Items.Add("Paquet '" + uneEtape.PaquetVersEmetteur + "' envoyé à l'émetteur.");
                picReceptVersEmet.Visible = true;
            }
            if (uneEtape.MsgEmetteur != null) //Primitive émetteur
            {
                lblMsgEmetteur.Text = uneEtape.MsgEmetteur;
                lstLog.Items.Add("Primitive '" + uneEtape.MsgEmetteur + "' reçue par l'émetteur.");
            }
            if (uneEtape.PaquetVersRecepteur != null) //Paquet récepteur vers emetteur
            {
                lblEmetVersRecept.Text = uneEtape.PaquetVersRecepteur;
                lstLog.Items.Add("Paquet '" + uneEtape.PaquetVersRecepteur + "' envoyé au récepteur.");
                picEmetVersRecept.Visible = true;
            }
            if (uneEtape.NextTabPage != null && uneEtape.CurrentTabPage != null)
            {
                tabctrlEtapes.TabPages.Insert(0, uneEtape.NextTabPage);
                tabctrlEtapes.TabPages.Remove(uneEtape.CurrentTabPage);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            lblEmetVersRecept.Text = "";
            picEmetVersRecept.Visible = false;
            lblReceptVersEmet.Text = "";
            picReceptVersEmet.Visible = false;
            lblMsgRecepteur.Text = "";
            lblMsgEmetteur.Text = "";
            tabctrlEtapes.TabPages.Remove(tabAttAckConnexion);
            tabctrlEtapes.TabPages.Remove(tabAttAckTransfert);
            tabctrlEtapes.TabPages.Remove(tabDeconnexion);
        }

        private void btnRestart_Click(object sender, EventArgs e)
        {
            if (tabctrlEtapes.SelectedTab != tabRepos)
            {
                Etape uneEtape = new Etape(null, null, null, null, tabctrlEtapes.SelectedTab, tabRepos);
                traitementsRetourRepos();
                traitementAffichages(uneEtape);
            }
        }
    }
}
